package com.xiaotu.service.impl;

import com.xiaotu.constant.CommonConstants;
import com.xiaotu.constant.ValidCode;
import com.xiaotu.mapper.VerifyCodeInfoMapper;
import com.xiaotu.model.VerifyCodeInfoModel;
import com.xiaotu.service.VerifyCodeInfoService;
import com.xiaotu.util.MsgUtils;
import com.xiaotu.util.UUIDUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.sql.Timestamp;
import java.util.Date;

/**
 * @author zhangxiao
 * @create 2022-03-08 16:14
 */
@Service
@Transactional
public class VerifyCodeInfoServiceImpl implements VerifyCodeInfoService {

    @Autowired
    private VerifyCodeInfoMapper verifyCodeInfoMapper;

    /**
     * 发送验证码
     * 先判断该手机号是否存在该种类型的有效验证码
     * <p>
     * 如果没有有效验证码，直接生成新的验证码，发送短信
     * <p>
     * 如果存在有效验证码，则判断验证码是否发送超过一分钟
     * 只有超过一分钟的时候才把原有验证码设为无效，生成新的验证码，发送短信
     * 如果没有超过一分钟，则不发送短信
     *
     * @param phone 手机号
     * @param type  验证码类型
     * @return 验证码
     */
    @Override
    public String sendVerifyCode(String phone, String type) {
        String code = UUIDUtils.getVerificationCode();
        //将历史验证码都设置为无效
        verifyCodeInfoMapper.updValidCodeInvalidByPhone(ValidCode.Invalid.getValue(), phone);
        //生成新的验证码，发送手机短信
        VerifyCodeInfoModel verifyCode = new VerifyCodeInfoModel();
        verifyCode.setPhone(phone);
        verifyCode.setCode(code);
        verifyCode.setValid(ValidCode.Valid.getValue());
        verifyCode.setType(type);
        verifyCode.setCreateTime(new Timestamp(System.currentTimeMillis()));
        verifyCodeInfoMapper.insertSelective(verifyCode);
        MsgUtils.sendMsg(phone, MsgUtils.ModelType.LOGIN_TEMPLATE_ID, new String[]{code, "2分钟"});
        return code;
    }

    /**
     * 验证验证码是否超时
     *
     * @param phone
     * @param type
     */
    @Override
    public boolean valiCodeOverTime(String phone, String type) {
        boolean isValiCodeOverTime = true;
        //查询该手机号该种类型的有效验证码
        VerifyCodeInfoModel existVerifyCode = verifyCodeInfoMapper.queryVaildCodeByPhoneAndType(phone, type);
        if (existVerifyCode != null) {
            Date lastSendDate = existVerifyCode.getCreateTime();
            //2分钟
            if (new Date().getTime() - lastSendDate.getTime() > CommonConstants.VERIFY_CODE_INVALID) {
                //验证码失效
                verifyCodeInfoMapper.updateValidCodeInvalid(ValidCode.Invalid.getValue(), existVerifyCode.getId());
                isValiCodeOverTime = false;
            }
        } else {
            isValiCodeOverTime = false;
        }
        return isValiCodeOverTime;
    }

    /**
     * 根据手机号和验证码查询有效的验证码
     *
     * @param phone
     * @param code
     * @return
     */
    @Override
    public VerifyCodeInfoModel queryByPhoneAndCode(String phone, String code, String type) {
        Example example = new Example(VerifyCodeInfoModel.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("phone", phone);
        criteria.andEqualTo("code", code);
        criteria.andEqualTo("valid", "1");
        criteria.andEqualTo("type", type);
        return verifyCodeInfoMapper.selectOneByExample(example);
    }

    /**
     * 设置指定手机号的所有验证码为无效
     *
     * @param phone
     */
    @Override
    public void inValidPhoneCode(String phone, String type) {
        VerifyCodeInfoModel model = new VerifyCodeInfoModel();
        model.setValid("0");
        Example example = new Example(VerifyCodeInfoModel.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("phone", phone);
        criteria.andEqualTo("type", type);
        criteria.andEqualTo("valid", "1");
        verifyCodeInfoMapper.updateByExampleSelective(model, example);
    }

}
